package org.simplextensions.ioc;

import org.simplextensions.annotations.AnnotationInfo;
import org.simplextensions.annotations.ioc.Point;
import org.simplextensions.annotations.ioc.Registry;
import org.simplextensions.annotations.ioc.ServiceDependency;
import org.simplextensions.registry.IExtensionRegistry;
import org.simplextensions.registry.IServiceRegistry;
import org.simplextensions.registry.phaselisteners.IDependencyLocator;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * 
 * @author Tomasz Krzyżak
 * 
 */
public class EnvironmentDependencyLocator implements IDependencyLocator {

	private IExtensionRegistry extensionRegistry;

	public EnvironmentDependencyLocator(IExtensionRegistry extensionRegistry) {
		init(extensionRegistry);
	}

	public Object getAnnotatedFieldValue(Field field, AnnotationInfo annotationInfo) {
		Object result = null;
		Class<?> fieldType = (Class<?>) field.getType();

		Annotation annotation = annotationInfo.getAnnotation();

		if (annotation instanceof ServiceDependency) {
			IServiceRegistry serviceRegistry = extensionRegistry.getExtensionPoint(IServiceRegistry.class);
			result = serviceRegistry.getService(fieldType);
		} else if (annotation instanceof Registry) {
			return extensionRegistry;
		} else if (annotation instanceof Point) {
			String ep_id = ((Point) annotation).value();
			if ("".equals(ep_id)) {
				result = extensionRegistry.getExtensionPoint((Class) fieldType);
			} else {
				result = extensionRegistry.getExtensionPoint((Class) fieldType, ep_id);
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public Class<? extends Annotation>[] getSupportedAnnotations() {
		return new Class[] { ServiceDependency.class, Registry.class, Point.class };
	}

	public void init(IExtensionRegistry extensionRegistry) {
		this.extensionRegistry = extensionRegistry;
	}
}
